package cn.org.xwb.common.encrypt.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * 和 DES 加密解密相关的工具类
 */
public class DesUtil {

    /**
     * 密钥长度
     */
    private static final Integer KEY_LENGTH = 24;

    /**
     * 偏移 iv 长度
     */
    private static final Integer IV_LENGTH = 8;

    /**
     * 加密算法
     */
    private static final String ALGORITHM = "DESede";

    /**
     * 加密算法：算法/ /填充模式
     */
    private static final String ALGORITHM_TRANSFORMATION = "DESede/CBC/PKCS5Padding";

    /**
     * DES 加密
     *
     * @param data 数据
     * @param key 密钥
     * @return 密文
     * @throws Exception
     */
    public static String encrypt(String data, String key) throws Exception {
        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
        byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
        // 生成 DES 密钥对象
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);
        // 加密器
        Cipher cipher = Cipher.getInstance(ALGORITHM_TRANSFORMATION);
        // 偏移
        IvParameterSpec iv = new IvParameterSpec(key.substring(0, 8).getBytes(StandardCharsets.UTF_8));
        // 加密器初始化
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
        // 加密
        byte[] encryptBytes = cipher.doFinal(dataBytes);
        return Base64.getEncoder().encodeToString(encryptBytes);
    }

    /**
     * DES 解密
     *
     * @param data 数据
     * @param key 密钥
     * @return 明文
     * @throws Exception
     */
    public static String decrypt(String data, String key) throws Exception {
        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
        byte[] dataBytes = Base64.getDecoder().decode(data);
        // 生成 DES 密钥对象
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);
        // 解密器
        Cipher cipher = Cipher.getInstance(ALGORITHM_TRANSFORMATION);
        // 偏移
        IvParameterSpec iv = new IvParameterSpec(key.substring(0, 8).getBytes(StandardCharsets.UTF_8));
        // 解密器初始化
        cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
        // 解密
        byte[] decryptBytes = cipher.doFinal(dataBytes);
        return new String(decryptBytes);
    }

}
